package com.baseproject.adapter;

import android.content.Context;
import android.support.v4.util.SparseArrayCompat;
import android.view.KeyEvent;
import android.view.ViewGroup;

/**
 * adapter中多个itemType管理类
 */
public class ItemViewDelegateManager<T> {
    SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat();

    DelegateManagerCallBack mCallBack;
    public ItemViewDelegateManager(DelegateManagerCallBack callBack) {
        mCallBack = callBack;
    }

    public int getItemViewCount() {
        int count = 0;
        for (int i = 0; i < delegates.size(); i++) {
            count += delegates.valueAt(i).getItemCount();
        }
        return count;
    }

    public int getItemViewDelegateTypeCount() {
        return delegates.size();
    }

    public void addItemViewDelegate(ItemViewDelegate itemViewDelegate) {
        addDelegate(itemViewDelegate);
        return;
    }

    public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate) {
        int size = delegates.size();
        if (delegate != null) {
            delegates.put(size, delegate);
        }
        return this;
    }

    public void updateData(int viewType, T t) {
        ItemViewDelegate<T> delegate = delegates.valueAt(viewType);
        delegate.updateData(t);
    }

    public boolean onKeyDown(int viewType, int keyCode, KeyEvent event) {
        ItemViewDelegate<T> delegate = delegates.valueAt(viewType);
        return delegate.onKeyDown(keyCode, event);
    }

    public int getItemViewType(int position) {
       return mCallBack.getDelegateTypePosition(position);
    }

    public ViewHolder createViewHolder(Context context, ViewGroup parent, int viewType) {
        ItemViewDelegate<T> delegate = delegates.valueAt(viewType);
        return delegate.createViewHolder(context, parent);
    }

    public void convert(ViewHolder holder, int position) {
        ItemViewDelegate<T> delegate;
        int delegatePosition = mCallBack.getDelegateTypePosition(position);
        delegate = delegates.valueAt(delegatePosition);
        int withinDelegateTypePosition = mCallBack.getWithinDelegateTypePosition(position);
        //给itemView设置实际position，如果item内还有其他需要设置点击事件的，还需要再具体delegate中设置其tag
        holder.itemView.setTag(withinDelegateTypePosition);
        delegate.convert(holder, withinDelegateTypePosition);
        return;
    }

    public interface DelegateManagerCallBack {
        int getDelegateTypePosition(int position);
        int getWithinDelegateTypePosition(int position);
    }

    public ItemViewDelegate getItemViewDelegate(int viewType) {
        return delegates.get(viewType);
    }

    public int getItemViewLayoutId(int viewType) {
        return getItemViewDelegate(viewType).getItemViewLayoutId();
    }

    public int getItemViewType(ItemViewDelegate itemViewDelegate) {
        return delegates.indexOfValue(itemViewDelegate);
    }

    public void addItemViewDelegate(int viewType, ItemViewDelegate<T> itemViewDelegate) {
        addDelegate(viewType, itemViewDelegate);
        return;
    }

    public ItemViewDelegateManager<T> addDelegate(int position, ItemViewDelegate<T> delegate) {
        if (delegates.get(position) != null) {
            throw new IllegalArgumentException(
                    "An ItemViewDelegate is already registered for the viewType = "
                            + position
                            + ". Already registered ItemViewDelegate is "
                            + delegates.get(position));
        }
        delegates.put(position, delegate);
        return this;
    }

    public ItemViewDelegateManager<T> removeDelegate(ItemViewDelegate<T> delegate) {
        if (delegate == null) {
            throw new NullPointerException("ItemViewDelegate is null");
        }
        int indexToRemove = delegates.indexOfValue(delegate);

        if (indexToRemove >= 0) {
            delegates.removeAt(indexToRemove);
        }
        return this;
    }

    public ItemViewDelegateManager<T> removeDelegate(int itemType) {
        int indexToRemove = delegates.indexOfKey(itemType);
        if (indexToRemove >= 0) {
            delegates.removeAt(indexToRemove);
        }
        return this;
    }

}
